import * as localforage from 'localforage'
import type { ILcCustomMessageItem } from './interface'
import CacheObject from './CacheObject'

export type LcSessionStorageOptions = {

  persistentOptions?: LocalForageOptions
  store?: LocalForage | null
  clearStores?: string[]
}
type IOTRestServiceCache = {
  chatList: CacheObject<ILcCustomMessageItem[]>
}
export type IOTRestServiceCacheOptions = {
  static?: boolean
  filter?: boolean
  persistent?: boolean
  persistentOptions?: LocalForageOptions
  store?: LocalForage | null
  clearStores?: string[]
}
export class LcSessionStorage {
  private static _instance: LcSessionStorage | null = null
  public static getInstance(options?: LcSessionStorageOptions) {
    if (!this._instance)
      this._instance = new this(options)

    return this._instance
  }

  private readonly store: LocalForage
  private cache: IOTRestServiceCache

  constructor(options?: LcSessionStorageOptions) {
    this.store = localforage.createInstance({
      driver: localforage.INDEXEDDB,
      name: 'local-xz-cache',
      storeName: 'chat_list',
      version: 1,
      ...options?.persistentOptions,
    });
    (options?.clearStores || []).forEach(v =>
      localforage.dropInstance({ name: v }),
    )
    this.cache = {
      chatList: CacheObject.create({
        key: 'chat_list',
        persistent: true,
        store: this.store,
      }),
    }
  }

  fetchChatList = async (conversationId: string) => {
    const chatStore = this.cache.chatList
    await chatStore.readFromStore()
    if (chatStore.isValid())
      return (await chatStore.getValue())!.filter(v => v.cid === conversationId)
    return []
  }

  answer = async (data: ILcCustomMessageItem | ILcCustomMessageItem[]) => {
    const chatStore = this.cache.chatList
    await chatStore.readFromStore()
    const currentData = await chatStore.getValue() || []
    await chatStore.setValue(currentData.concat(data))
    return true
  }

  deleteConversation = async (conversationId: string) => {
    const chatStore = this.cache.chatList
    await chatStore.readFromStore()
    if (chatStore.isValid()) {
      const data = (await chatStore.getValue())!.filter(v => v.cid !== conversationId)
      await chatStore.setValue(data)
      return true
    }
    return false
  }

  clear = async () => {
    const chatStore = this.cache.chatList
    await chatStore.readFromStore()
    if (chatStore.isValid()) {
      await chatStore.setValue([])
      return true
    }
    return false
  }
}
